﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Labthink.PCSoft.UniversalHost4.Instrument.MyControls
{
    /// <summary>
    /// 按照步骤 1a 或 1b 操作，然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
    ///
    /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    /// 元素中: 
    ///
    ///     xmlns:MyNamespace="clr-namespace:C190M.MyControls"
    ///
    ///
    /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    /// 元素中: 
    ///
    ///     xmlns:MyNamespace="clr-namespace:C190M.MyControls;assembly=C190M.MyControls"
    ///
    /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用，
    /// 并重新生成以避免编译错误: 
    ///
    ///     在解决方案资源管理器中右击目标项目，然后依次单击
    ///     “添加引用”->“项目”->[浏览查找并选择此项目]
    ///
    ///
    /// 步骤 2)
    /// 继续操作并在 XAML 文件中使用控件。
    ///
    ///     <MyNamespace:UcArrow/>
    ///
    /// </summary>
    public class UcArrow : Control
    {
        static UcArrow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(UcArrow), new FrameworkPropertyMetadata(typeof(UcArrow)));
        }

        public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(nameof(Stroke), typeof(Brush), typeof(UcArrow), new PropertyMetadata(Brushes.Gray));

        public Brush Stroke
        {
            get => (Brush)GetValue(StrokeProperty);
            set => SetValue(StrokeProperty, value);
        }

        public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
            nameof(Fill), typeof(Brush), typeof(UcArrow), new PropertyMetadata(Brushes.LightGray));

        public Brush Fill
        {
            get => (Brush)GetValue(FillProperty);
            set => SetValue(FillProperty, value);
        }

        public static readonly DependencyProperty StrokeDashArrayProperty = DependencyProperty.Register(
           nameof(StrokeDashArray), typeof(DoubleCollection), typeof(UcArrow), new PropertyMetadata(default(DoubleCollection)));

        public DoubleCollection StrokeDashArray
        {
            get => (DoubleCollection)GetValue(StrokeDashArrayProperty);
            set => SetValue(StrokeDashArrayProperty, value);
        }

        public static readonly DependencyProperty ThicknessProperty = DependencyProperty.Register(
            nameof(Thickness), typeof(double), typeof(UcArrow), new PropertyMetadata(default(double)));

        public double Thickness
        {
            get => (double)GetValue(ThicknessProperty);
            set => SetValue(ThicknessProperty, value);
        }

        public static readonly DependencyProperty AnimaticProperty = DependencyProperty.Register(
            nameof(Animatic), typeof(bool), typeof(UcArrow), new PropertyMetadata(default(bool), AnimaticChanged));

        private static void AnimaticChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is UcArrow a)
            {
                if (e.NewValue != e.OldValue)
                {
                    a.Animate((bool)e.NewValue);
                }
            }
        }

        public bool Animatic
        {
            get => (bool)GetValue(AnimaticProperty);
            set => SetValue(AnimaticProperty, value);
        }

        public static readonly DependencyProperty ScheduleProperty = DependencyProperty.Register(
            nameof(Schedule), typeof(double), typeof(UcArrow), new PropertyMetadata(default(double), ScheduleChanged));

        private static void ScheduleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if(d is UcArrow a)
            {
                if (e.NewValue != e.OldValue) a.ChangeWidth((double)e.NewValue);
            }
        }

        public double Schedule
        {
            get => (double) GetValue(ScheduleProperty);
            set => SetValue(ScheduleProperty, value);
        }

        private Path _path;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _path = GetTemplateChild("PProcess") as Path;
        }

        public void Animate(bool a)
        {
            if(_path == null) return;
            if (!a) _path.BeginAnimation(WidthProperty, null);
            else
            {
                var da = new DoubleAnimation
                {
                    RepeatBehavior = RepeatBehavior.Forever,
                    From = 0,
                    To = 150,
                    Duration = new TimeSpan(0, 0, 3)
                };
                _path.BeginAnimation(WidthProperty, da);
            }
        }

        public void ChangeWidth(double d)
        {
            if (_path == null) return;
            if (d > 100) d = 100;
            if (d < 0) d=0;
            _path.Width = 150 * d / 100;
        }
    }
}
